#include "Sys.h"

#ifndef __USE_BSD
#define __USE_BSD
#endif
#include <stdlib.h>
#include <unistd.h>
#include "Str.h"
#include "../../config.h"


static List* kArgs;
static Map* kEnv;
static Str* kOS;
static Str* kArch;
static Str* kPlatform;
static Str* kHostName;
static Str* kUserName;


/**********************************************
 *
 * Extra methods
 *
 **********************************************/


/* Called to initialize the "sys" pod when the runtime boots.
 * The command-line args and the environment-vars are passed. */
void Sys_boot(List* args, Map* env)
{
  kArgs = VAL_GET_REF(Obj_toImmutable(VAL_MAKE_REF(args)));
  kEnv = VAL_GET_REF(Obj_toImmutable(VAL_MAKE_REF(env)));

  kOS = Str_createFromCStr(FAN_SYSTEM_NAME);
  kArch = Str_createFromCStr(FAN_SYSTEM_ARCH);
  kPlatform = Str_createWithFormat("%r-%r", kOS, kArch);

  char hostName[1024];
  hostName[1023] = '\0';
  if (gethostname(hostName, 1023) == 0)
    kHostName = Str_createFromCStr(hostName);
  else
    kHostName = Str_defVal();

  const char* userName;
  userName = getenv("USER");
  if (userName == NULL)
    userName = getenv("USERNAME");
  kUserName = (userName != NULL) ? Str_createFromCStr(userName) : Str_defVal();
}


/* static Str[] args() */
List* Sys_args(void)
{
  return kArgs;
}


/* static Str:Str env() */
Map* Sys_env(void)
{
  return kEnv;
}


/* static Str os() */
Str* Sys_os(void)
{
  return kOS;
}


/* static Str arch() */
Str* Sys_arch(void)
{
  return kArch;
}


/* static Str platform() */
Str* Sys_platform(void)
{
  return kPlatform;
}


/* static Str:Obj diagnostics() */
Map* Sys_diagnostics(void)
{
  //TODO: IMPL Sys_diagnostics
  return NULL;
}


/* static Void gc() */
void Sys_gc(void)
{
  //TODO: IMPL Sys_gc
}


/* static Str host() */
Str* Sys_hostName(void)
{
  return kHostName;
}


/* static Str user() */
Str* Sys_userName(void)
{
  return kUserName;
}


/* static Void exit(Int status := 0) */
void Sys_exit(Int status)
{
  exit(status);
}


/* static InStream in() */
InStream* Sys_in(void)
{
  //TODO: IMPL Sys_in
  return NULL;
}


/* static OutStream out() */
OutStream* Sys_out(void)
{
  //TODO: IMPL Sys_out
  return NULL;
}


/* static OutStream err() */
OutStream* Sys_err(void)
{
  //TODO: IMPL Sys_err
  return NULL;
}
